self.addEventListener('message', (e) => {
    // 获取对应的值
    let cameraInfo = e.data.cameraInfo;
    let model = e.data.model;
    // 计算过程
    // 0. 创建缓存 以及 存储结果的列表
    let cache = {};
    let planeList = [];
    // 1. 获取模型里的每一个平面
    let modelPlaneList = model.planeList;
    // 2. 遍历每一个平面进行坐标换算
    for (let i = 0; i < modelPlaneList.length; i++) {
        // 3. 获取当前平面的坐标
        let item = modelPlaneList[i];
        // 4. 创建结果列表
        let newRes = [];
        // 5. 计算当前平面的坐标
        newRes.push(worldToCamera(cameraInfo, item[0], cache));
        newRes.push(worldToCamera(cameraInfo, item[1], cache));
        newRes.push(worldToCamera(cameraInfo, item[2], cache));
        newRes.push(item[3] ? item[3] : model.default_color);
        // 5. 将坐标换算后的平面坐标赋值给 plane
        planeList.push(newRes);
    }
    // 发送结果回主线程
    let resData = { planeList };
    self.postMessage(resData);
});

function worldToCamera(cameraInfo, point, cache) {
    // 尝试读取缓存
    let pointStr = point.toString();
    let cacheResult = cache[pointStr];
    // 缓存命中时直接返回结果
    if (cacheResult) {
        return cacheResult;
    }
    // 缓存不命中的时候进行计算
    // 1. 计算出 将要绘制的点 相对于 相机而言 的 相对坐标
    point[0] -= cameraInfo.position[0];
    point[1] -= cameraInfo.position[1];
    point[2] -= cameraInfo.position[2];
    // 2. 计算出 将要绘制的点 的朝向
    // 2.1 计算出左右朝向
    let lrRes = 0;
    if (point[0] == 0) {
        if (point[1] == 0) {
            lrRes = 0;
        } else {
            lrRes = point[2] > 0 ? 90 : -90;
        }
    } else if (point[1] == 0) {
        lrRes = point[0] > 0 ? 0 : 180;
    } else {
        // 2.1.1 计算反正切值，返回的是弧度
        let angleInRadians = Math.atan(point[1] / point[0]);
        // 2.1.2 将弧度转换为度数 -180 ~ 180
        lrRes = angleInRadians * (180 / Math.PI) - (point[0] < 0 ? 180 : 0);

    }
    // 2.2 计算出上下朝向
    let tbRes = 0;
    // 2.2.1 计算出 xy平面 的模长
    let xyLength = Math.sqrt(point[0] * point[0] + point[1] * point[1]);
    if (xyLength == 0) {
        tbRes = point[2] > 0 ? 0 : 180;
    } else {
        // 2.2.2 计算反正切值，返回的是弧度
        let angleInRadians = Math.atan(point[2] / xyLength);
        // 2.2.3 将弧度转换为度数
        tbRes = angleInRadians * (180 / Math.PI);
    }
    // 2.3 计算出 将要绘制的点 相对于 相机朝向 的 相对朝向
    let result = [lrRes - cameraInfo.fov[0], tbRes - cameraInfo.fov[1]];
    // 2.4 将计算结果控制在 -180 ~ 180 范围之内
    result[0] = result[0] % 360 + (result[0] <= -180 ? 360 : 0);
    result[0] -= (result[0] >= 180 ? 180 : 0);
    // 2.5 根据相对朝向计算出 映射到 2d 平面的坐标点
    let drowWidth = cameraInfo.width;
    let drowHeight = cameraInfo.height;
    result[0] = Math.round(result[0] / 60 * drowWidth + drowWidth / 2);
    // result[1] = Math.round(result[1] / 60 * drowHeight + drowHeight / 2);
    result[1] = Math.round(drowHeight / 2 - result[1] / 60 * drowHeight);
    // 计算结果加入缓存
    cache[pointStr] = result;
    // 返回计算结果
    return result;
}